package com.sky.service.impl;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.sky.constant.MessageConstant;
import com.sky.constant.StatusConstant;
import com.sky.dto.SetmealDTO;
import com.sky.dto.SetmealPageQueryDTO;
import com.sky.entity.Dish;
import com.sky.entity.Setmeal;
import com.sky.entity.SetmealDish;
import com.sky.exception.DeletionNotAllowedException;
import com.sky.exception.SetmealEnableFailedException;
import com.sky.mapper.DishMapper;
import com.sky.mapper.SetmealDishMapper;
import com.sky.mapper.SetmealMapper;
import com.sky.result.PageResult;
import com.sky.service.SetmealService;
import com.sky.vo.DishItemVO;
import com.sky.vo.SetmealVO;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
@Service
public class SetmealServiceImpl implements SetmealService {

    @Autowired
    private SetmealMapper setmealMapper;

    @Autowired
    private SetmealDishMapper setmealDishMapper;

    @Autowired
    private DishMapper dishMapper;

    /**
     * 新增套餐,同时需要保存套餐和菜品的关联关系
     * @param setmealDTO
     */
    @Override
    @Transactional
    public void saveWithDish(SetmealDTO setmealDTO) {

        Setmeal setmeal = new Setmeal();
        BeanUtils.copyProperties(setmealDTO, setmeal);
        //把基本信息导入到setmeal数据库中
        setmealMapper.insert(setmeal);
        Long setmealId = setmeal.getId();
        List<SetmealDish> setmealDishes = setmealDTO.getSetmealDishes();
        setmealDishes.forEach(setmealDish -> {
            setmealDish.setSetmealId(setmealId);//得点保存 setmealId才会生成 所以这里得xml文件中返回setmealId

        });
        //
        setmealDishMapper.insertBatch(setmealDishes);


    }


    @Override
    public PageResult pageQuery(SetmealPageQueryDTO setmealPageQueryDTO) {
        //动态查询
        PageHelper.startPage(setmealPageQueryDTO.getPage(), setmealPageQueryDTO.getPageSize());
        Page<SetmealVO> page = setmealMapper.select(setmealPageQueryDTO);
//        List result = page.getResult();
//

/*        long total = page.getTotal();
        pageResult.setTotal(total);
        pageResult.setRecords(result);
*//*        SetmealVO; 要注意VO和DTO的区别 VO比DTO多了返回类型所需要的updateTime和updateUser
        SetmealDTO;*//*
        //所以Page的泛型是SetmealVO  正好从setmeal那拿得到那个updatetime
        return pageResult;*/
        return new PageResult(page.getTotal(), page.getResult());
    }

    @Override
    public void deleteBatch(List<Long> ids) {
        //根据ids查询起售状态
        //注意 这里的id不是 菜品dish 的id 而是套餐 setmeal的id
        //List<Integer> statuses= setmealMapper.selectByIds(ids); //这里不能传递ids进入mappder 层 因为返回值无法设置为status泛型 只能是Integer 无法完成对应的封装 而之前时进行批量删除操作是没有返回值的 所以可以传递ids集合进入mapper
/*
        for (Integer status : statuses) {
            if (status!= StatusConstant.DISABLE){
                throw new DeletionNotAllowedException( MessageConstant.SETMEAL_ON_SALE);
            }
            else   setmealDishMapper.deleteSetmealBatch(ids);
        }*/
        //将ids遍历封装进入setmeal 记住这个id代表谁的id 是setmeal的id
        //删除套餐,但是套餐有起售状态就不删除
        ids.forEach(id -> {
            Setmeal setmeal = setmealMapper.getById(id);//为了获取起售状态
            if (setmeal.getStatus()==StatusConstant.ENABLE){
                throw new DeletionNotAllowedException(MessageConstant.SETMEAL_ON_SALE);}
                setmealMapper.delect(id);
                setmealDishMapper.deleteSetmealById(id);
        });
            //进行删除套餐操作
            //不用传一个套餐对象进去 我直接传id 因为是删除操作





    }
    /**根据id查询套餐和套餐菜品关系
     *
     * @param
     * @return
     */
/*    @Override
    public SetmealVO selectById(Long id) {
        return setmealDishMapper.selectBySetmealId(id);

    }*/
    public SetmealVO selectById(Long id) {
        Setmeal setmeal = setmealMapper.getById(id);
        List<SetmealDish> setmealDishes = setmealDishMapper.getBySetmealId(id);

        SetmealVO setmealVO = new SetmealVO();
        BeanUtils.copyProperties(setmeal, setmealVO);
        setmealVO.setSetmealDishes(setmealDishes);

        return setmealVO;
    }

    /**
     * 修改套餐
     * @param setmealDTO
     */
    @Override
    public void update(SetmealDTO setmealDTO) {
        Setmeal setmeal=new Setmeal();
        BeanUtils.copyProperties(setmealDTO,setmeal);
         setmealMapper.update(setmeal);
         //想获得套餐id
        Long setmealId = setmealDTO.getId();
        //根据套餐id清空菜品套餐关系表数据
        // 先进行删除 将套餐下关联的菜品清空 再重新添加
        // 都删除了 就无法修改了能做到的是重新批量插入
        setmealDishMapper.deleteSetmealById(setmealId);

        List<SetmealDish> setmealDishes = setmealDTO.getSetmealDishes();

        setmealDishes.forEach(setmealDish -> {
            //在菜品套餐关系中 此时 并没有套餐id setmealId=null 套餐id值是null的
            //我们得根据setmealDTO 赋值给套餐菜品对象
            setmealDish.setSetmealId(setmealId);
        });
        setmealDishMapper.insertBatch(setmealDishes);
    }

/*    @Override
    public void startOrStop(Integer status, Long id) {
        //业务规则 停售某个套餐时,套餐内部有起售的菜品 则不能停售  //新建套餐默认是0
        //上面的业务规则错了,是起售某个套餐时,套餐内是否有停售的商品,有的话就提示套餐内包含为起售菜品,套餐无法起售
        //根据id 查询 套餐表菜品表中 菜品id
        //根据菜品id 查询 菜品表中 菜品的起售状态
        //若起售状态为起售 则抛出异常
        Setmeal setmeal=new Setmeal();
        setmeal.setStatus(status);
        setmeal.setId(id);
        SetmealVO setmealVO=setmealDishMapper.selectBySetmealId(id);
        Integer dishStatus = setmealVO.getStatus();//没有考虑到一个套餐内可能会有 部分菜品停售 部分菜品起售
        if (dishStatus==StatusConstant.ENABLE){
            throw new SetmealEnableFailedException(MessageConstant.SETMEAL_ENABLE_FAILED);

        }
        //进行停售 根据 套餐id 修改套餐表中status字段
        setmealMapper.update(setmeal);
    }*/

    /**
     * 套餐起售、停售
     * @param status
     * @param id
     */
    public void startOrStop(Integer status, Long id) {
        //起售套餐时，判断套餐内是否有停售菜品，有停售菜品提示"套餐内包含未启售菜品，无法启售"
        if(status == StatusConstant.ENABLE){
            //select a.* from dish a left join setmeal_dish b on a.id = b.dish_id where b.setmeal_id = ?
            List<Dish> dishList = dishMapper.getBySetmealId(id);
            if(dishList != null && dishList.size() > 0){
                dishList.forEach(dish -> {
                    if(StatusConstant.DISABLE == dish.getStatus()){
                        throw new SetmealEnableFailedException(MessageConstant.SETMEAL_ENABLE_FAILED);
                    }
                });
            }
        }
        //走这条路 就说明走套餐停售路线
        Setmeal setmeal = Setmeal.builder()
                .id(id)
                .status(status)
                .build();
        setmealMapper.update(setmeal);
    }

    /**
     * 条件查询
     * @param setmeal
     * @return
     */
    public List<Setmeal> list(Setmeal setmeal) {
        List<Setmeal> list = setmealMapper.list(setmeal);
        return list;
    }

    /**
     * 根据id查询菜品选项
     * @param id
     * @return
     */
    public List<DishItemVO> getDishItemById(Long id) {
        return setmealMapper.getDishItemBySetmealId(id);
    }
}
